package cn.com.checne.controller.front;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermRangeFilter;
import org.apache.lucene.search.TopScoreDocCollector;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.store.LockObtainFailedException;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
import org.wltea.analyzer.lucene.IKQueryParser;
import org.wltea.analyzer.lucene.IKSimilarity;

import cn.com.checne.constants.Constants;
import cn.com.checne.constants.LuceneConstants;
import cn.com.checne.dao.BusinessInfoDao;
import cn.com.checne.dao.IntroduceInfoDao;
import cn.com.checne.dao.JobInfoDao;
import cn.com.checne.dao.JobNewsInfoDao;
import cn.com.checne.dao.NewsInfoDao;
import cn.com.checne.dao.PerformanceInfoDao;
import cn.com.checne.model.domain.BusinessInfo;
import cn.com.checne.model.domain.IntroduceInfo;
import cn.com.checne.model.domain.JobInfo;
import cn.com.checne.model.domain.JobNewsInfo;
import cn.com.checne.model.domain.LuceneEntry;
import cn.com.checne.model.domain.NewsInfo;
import cn.com.checne.model.domain.PerformanceInfo;
import cn.com.checne.model.dto.BusinessQuery;
import cn.com.checne.model.dto.IntroduceQuery;
import cn.com.checne.model.dto.JobNewsQuery;
import cn.com.checne.model.dto.JobQuery;
import cn.com.checne.model.dto.NewsQuery;
import cn.com.checne.model.dto.PerformanceQuery;
import cn.com.checne.util.FileUtils;
import cn.com.checne.util.HeaderUtils;
import cn.com.checne.util.LanguageUtils;
import cn.com.checne.util.LuceneUtils;
import cn.com.checne.util.PageBean;
import cn.com.checne.util.StringTools;

@Controller
public class LuceneFrontController {
	protected static final Logger logger = Logger.getLogger(LuceneFrontController.class);

	@Resource
	private IntroduceInfoDao introduceDao;
	@Resource
	private BusinessInfoDao businessDao ;
	@Resource
	private PerformanceInfoDao performanceDao ;
	@Resource
	private NewsInfoDao newsDao ;
	@Resource
	private JobNewsInfoDao jobNewsDao ;
	@Resource
	private JobInfoDao jobDao ;

	private LuceneUtils lu = new LuceneUtils();
	private static Directory directory = null;
	private static IndexSearcher isearcher = null;
	
	
	//全站搜索
	@RequestMapping(value="/{lg}/search",method=RequestMethod.GET)
	public ModelAndView dd(
			@PathVariable String lg,
			@RequestParam(value = "kw", required = false, defaultValue = "") String kw,
			@RequestParam(value = "curPage", required = false, defaultValue = "1") String pg,
			HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws Exception {
		
		ModelAndView mav = new ModelAndView();
		lg = StringUtils.isBlank(lg) ? Constants.LANGUAGE_CN : lg ;
		String viewName = "front/" + lg + "/search" ;
		int languageId = LanguageUtils.getLanguage(lg);
		int curPage = Integer.parseInt(pg);
		kw = StringTools.converISO2UTF8(kw);
		kw = StringEscapeUtils.unescapeHtml(kw);
		PageBean pageBean = new PageBean();
		pageBean.setCurPage(curPage);
		List<LuceneEntry> entries = new ArrayList<LuceneEntry>();
 		
		
		FileUtils.mkdirs(LuceneConstants.INDEXDIR);
		try {
			directory = FSDirectory.open(LuceneConstants.INDEXDIR);
			isearcher = new IndexSearcher(directory);			
			isearcher.setSimilarity(new IKSimilarity());
			String fieldNames [] = {LuceneConstants.flTitle,LuceneConstants.flContent} ;
			Query query = IKQueryParser.parseMultiField(fieldNames, kw);
			//在指定分类语种下进行搜索
			Filter filter = new TermRangeFilter(LuceneUtils.flLg, String.valueOf(languageId), String.valueOf(languageId), true, true);
			TopScoreDocCollector topCollector = TopScoreDocCollector.create(isearcher.maxDoc(), true);
			isearcher.search(query, filter, topCollector);
			
			int maxRowCount = topCollector.getTotalHits();
			pageBean.setMaxRowCount(maxRowCount);
			pageBean.setMaxPage();
			pageBean.setPageNoList();
			
			
			ScoreDoc docs [] = topCollector.topDocs(pageBean.getStart(), pageBean.getRowsPerPage()).scoreDocs;
			LuceneEntry entry = null ;
			String title = "" ;
			for(ScoreDoc sDoc : docs){
				entry = new LuceneEntry();
				Document doc = isearcher.doc(sDoc.doc);
				title = doc.get(LuceneConstants.flTitle);
				// 高亮显示
//				title = LuceneUtils.getHighlighter(query, doc, LuceneConstants.flTitle, kw, null,null);
				entry.setId(Integer.parseInt(doc.get(LuceneConstants.flID)));
				entry.setLanguageId(Integer.parseInt(doc.get(LuceneConstants.flLg)));
				entry.setModel(doc.get(LuceneConstants.flModel));
				entry.setHref(doc.get(LuceneConstants.flHref));
				entry.setTitle(title);
				entry.setContent(doc.get(LuceneConstants.flContent));
				
				entries.add(entry);
			}
			
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally{
			if(isearcher != null)
				try {
					isearcher.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			if(directory != null){
				try {
					directory.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
 		modelMap.put("entries", entries);
 		modelMap.put("pageBean", pageBean);
 		modelMap.put("kw", StringEscapeUtils.escapeHtml(kw));
		modelMap.addAllAttributes(LanguageUtils.getModelMap(lg));
		modelMap.addAllAttributes(HeaderUtils.getHeaderMap(languageId));
		mav.setViewName(viewName);
		mav.addAllObjects(modelMap);
		return mav ;
	}
	
	
	//创建索引
	@RequestMapping(value="/lucene/build.do",method=RequestMethod.GET)
	public ModelAndView luceneBuild(
			@RequestParam(value = "lg", required = false, defaultValue = "cn") String lg,
			HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws Exception {
		
		ModelAndView mav = new ModelAndView();
		String viewName = "common/message" ;
		int languageId = LanguageUtils.getLanguage(lg);
		
		List<LuceneEntry> entries = new ArrayList<LuceneEntry>();
		LuceneEntry entry = null ;

		//公司概况
		IntroduceQuery inQuery = new IntroduceQuery();
		inQuery.setLanguageId(languageId);
		List<IntroduceInfo> introduceList = introduceDao.getIntroduceListByCondition(inQuery, 0,Integer.MAX_VALUE);
		for(IntroduceInfo obj : introduceList){
			entry = new LuceneEntry();
			entry.setId(obj.getIntroduceId());
			entry.setLanguageId(languageId);
			entry.setModel("introduce");
			entry.setHref(lg + "/introduce/" + entry.getId());
			entry.setTitle(obj.getTitle());
			entry.setContent(obj.getContent());
			entries.add(entry);
		}
		
		//公司业务
		BusinessQuery buQuery = new BusinessQuery();
		buQuery.setLanguageId(languageId);
		List<BusinessInfo> businessList = businessDao.getBusinessListByCondition(buQuery, 0, Integer.MAX_VALUE);
		for(BusinessInfo obj : businessList){
			entry = new LuceneEntry();
			entry.setId(obj.getBusinessId());
			entry.setLanguageId(languageId);
			entry.setModel("business");
			entry.setHref(lg + "/business/" + entry.getId());
			entry.setTitle(obj.getTitle());
			entry.setContent(obj.getContent());
			entries.add(entry);
		}
		
		
		//公司业绩
		PerformanceQuery perQuery = new PerformanceQuery();
		buQuery.setLanguageId(languageId);
		List<PerformanceInfo> performanceList = performanceDao.getPerformanceListByCondition(perQuery,  0, Integer.MAX_VALUE);
		for(PerformanceInfo obj : performanceList){
			entry = new LuceneEntry();
			entry.setId(obj.getPerformanceId());
			entry.setLanguageId(languageId);
			entry.setModel("performance");
			entry.setHref(lg + "/performance/" + entry.getId());
			entry.setTitle(obj.getTitle());
			entry.setContent(obj.getContent());
			entries.add(entry);
		}
		
		//公司新闻
		NewsQuery newsQuery = new NewsQuery();
		newsQuery.setLanguageId(languageId);
		List<NewsInfo> newsList = newsDao.getNewsListByCondition(newsQuery, 0, Integer.MAX_VALUE);
		for(NewsInfo obj : newsList){
			entry = new LuceneEntry();
			entry.setId(obj.getNewsId());
			entry.setLanguageId(languageId);
			entry.setModel("news");
			entry.setHref(lg + "/news/" + entry.getId());
			entry.setTitle(obj.getTitle());
			entry.setContent(obj.getContent());
			entries.add(entry);
		}
		
		//招聘新闻
		JobNewsQuery jobNewsQuery = new JobNewsQuery();
		jobNewsQuery.setLanguageId(languageId);
		List<JobNewsInfo> jobNewsList = jobNewsDao.getJobNewsListByCondition(jobNewsQuery,  0, Integer.MAX_VALUE);
		for(JobNewsInfo obj : jobNewsList){
			entry = new LuceneEntry();
			entry.setId(obj.getJobNewsId());
			entry.setLanguageId(languageId);
			entry.setModel("hr");
			entry.setHref(lg + "/hr/" + entry.getId());
			entry.setTitle(obj.getTitle());
			entry.setContent(obj.getContent());
			entries.add(entry);
		}
		
		
		//招聘岗位
		JobQuery jobQuery = new JobQuery();
		jobQuery.setLanguageId(languageId);
		List<JobInfo> jobList = jobDao.getJobListByCondition(jobQuery, 0, Integer.MAX_VALUE);;
		for(JobInfo obj : jobList){
			entry = new LuceneEntry();
			entry.setId(obj.getJobId());
			entry.setLanguageId(languageId);
			entry.setModel("job");
			entry.setHref(lg + "/job/" + obj.getJobCategory().getCateId() + "/" + entry.getId());
			entry.setTitle(obj.getTitle());
			entry.setContent(obj.getRequirement() + "  " + obj.getResponsibility());
			entries.add(entry);
		}
		lu.createIndex(true, entries);
		modelMap.put("message", "全站索引生成成功!");
		mav.setViewName(viewName);
		mav.addAllObjects(modelMap);
		return mav ;
	}
	
	//创建索引页面
	@RequestMapping(value="/lucene/show.do",method=RequestMethod.GET)
	public ModelAndView luceneShow(
			HttpServletRequest request,HttpServletResponse response, ModelMap modelMap) throws Exception {
		ModelAndView mav = new ModelAndView();
		mav.setViewName("super/sysSetUp/lucene-show");
		mav.addAllObjects(modelMap);
		return mav ;
	}
}